package mynet

import (
	"bufio"
	"fmt"
	"github.com/sirupsen/logrus"
	"io"
	"net"
	"regexp"
	"strconv"
	"strings"
	"udp_tcp_client/util"
)

var ContentLengthRegexp = regexp.MustCompile("Content-Length:(.+)")

func TcpServer(port int) {
	addr, err := net.ResolveTCPAddr(util.NETWORK_TCP, fmt.Sprintf("%s:%d", "0.0.0.0", port))
	if err != nil {
		logrus.Panicln("tcp端口监听错误1:", err)
		panic(fmt.Errorf("tcp端口监听错误1:%v", err))
	}

	listen, err := net.ListenTCP(util.NETWORK_TCP, addr)
	if err != nil {
		logrus.Panicln("tcp端口监听错误2:", err)
		panic(fmt.Errorf("tcp端口监听错误2:%v", err))
	}

	defer listen.Close()

	logrus.Infoln("tcp端口监听于端口:", port)

	util.TcpConnMap = make(map[string]*net.TCPConn)
	util.Process = process

	for {
		conn, err := listen.AcceptTCP()
		if err != nil {
			logrus.Errorln("accept fail,err:", err)
			continue
		}

		go process(conn)
	}
}

func process(conn *net.TCPConn) {
	util.TcpConnMap[conn.RemoteAddr().String()] = conn

	defer func() {
		delete(util.TcpConnMap, conn.RemoteAddr().String())

		conn.Close()
	}()

	reader := bufio.NewReader(conn)
	for {
		builder := strings.Builder{}
		for {
			item, err := reader.ReadString('\n')
			if err != nil && err != io.EOF {
				logrus.Infoln("tcp读取item失败:", err)
				return
			}
			builder.WriteString(item)
			if err == io.EOF || item == util.CRLF {
				break
			}
		}
		matches := ContentLengthRegexp.FindStringSubmatch(builder.String())
		if len(matches) > 1 {
			length, _ := strconv.Atoi(strings.TrimSpace(matches[1]))
			if length > 0 {
				buff := make([]byte, length)
				count, err := reader.Read(buff)
				if err != nil && err != io.EOF {
					logrus.Infoln("tcp读取body失败:", err)
					return
				}
				builder.WriteString(string(buff[:count]))
			}
			go func() {
				addr := conn.RemoteAddr().(*net.TCPAddr)
				logrus.Info(builder.String(), util.NETWORK_TCP, addr.IP.String(), addr.Port)
			}()

		}
	}
}
